﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TouchModel2RotateCamera : MonoBehaviour
{
    public float rotateSpeed = 1.2f;
    public int rotateFinishLength = 90;

    Transform target;
    Vector3 inputDirection = Vector3.zero;
    Vector3 oldInputDirection = Vector3.zero;
    List<Transform> targetList = new List<Transform>();
    List<Vector3> inputDirectionList = new List<Vector3>();

    void Update()
    {
        if( !GetComponent<Camera>() )
            this.enabled = false;

        Pick();
    }

    bool IsMobile { get { return Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer; } }
    bool IsTouch { get { return IsMobile ? Input.touchCount > 0 : Input.GetMouseButton( 0 ); } }
    Vector3 GetTouchPosition() { return IsMobile ? MyUtil.Vector2to3( Input.touches[0].position ) : Input.mousePosition; }
    Vector3 GetDeltaPosition() { return GetTouchPosition() - oldInputDirection; }

    void Pick()
    {
        if( IsTouch )
        {
            RaycastHit hit;
            if( !target && Physics.Raycast( Camera.main.ScreenPointToRay( GetTouchPosition() ), out hit ) )
            {
                if( hit.transform.gameObject.GetComponent<TouchModel2RotateTarget>() )
				{
					oldInputDirection = GetTouchPosition();
					target = hit.transform;
					if( targetList.Contains( target ) )
					{
						inputDirectionList.RemoveAt( targetList.IndexOf( target ) );
						targetList.Remove( target );
					}
                }
            }
			Spin();
			oldInputDirection = GetTouchPosition();
        }
        else
        {
            if( target )
            {
                targetList.Add( target );
                inputDirectionList.Add( inputDirection );
                target = null;
                inputDirection = Vector3.zero;
            }
        }
        SpinFinish();
    }

    void Spin()
    {
        if( target )
        {
            Vector3 deltaPos = GetDeltaPosition();
            inputDirection = Vector3.zero;

            TouchModel2RotateTarget rotTarget = target.GetComponent<TouchModel2RotateTarget>();

            if( deltaPos.x > 0f && ( int ) ( rotTarget.rotateDirection & TouchModel2RotateTarget.RotateDirection.Right ) > 0 )
                inputDirection.y = -deltaPos.x;
            else if( deltaPos.x < 0f && ( int ) ( rotTarget.rotateDirection & TouchModel2RotateTarget.RotateDirection.Left ) > 0 )
                inputDirection.y = -deltaPos.x;

            if( deltaPos.y > 0f && ( int ) ( rotTarget.rotateDirection & TouchModel2RotateTarget.RotateDirection.Up ) > 0 )
                inputDirection.x = deltaPos.y;
            else if( deltaPos.y < 0f && ( int ) ( rotTarget.rotateDirection & TouchModel2RotateTarget.RotateDirection.Down ) > 0 )
                inputDirection.x = deltaPos.y;

            inputDirection.z = 0f;
            target.Rotate( inputDirection * rotateSpeed * ( IsMobile  ? 0.25f : 1f ) );
        }
    }

    void SpinFinish()
    {
        Vector3 dir;
        for( int i = 0; i < targetList.Count; i ++ )
        {
            dir = inputDirectionList[i];
            if( !dir.Equals( Vector3.zero ) && targetList[i] )
            {
                targetList[i].Rotate( dir * rotateSpeed * .1f * ( IsMobile ? 0.5f : 1f ) );
                dir *= MyUtil.Clamp( rotateFinishLength/100f, 0f, 1f );

                if( Mathf.Abs( dir.x ) < 0.001f )
                    dir.x = 0f;
                if( Mathf.Abs( dir.y ) < 0.001f )
                    dir.y = 0f;
                inputDirectionList[i] = dir;
            }
            else
            {
                inputDirectionList.RemoveAt( i );
                targetList.RemoveAt( i );
            }
        }
    }
}